package cn.bugstack.domain.deepseek.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class ChatService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private OkHttpClient okHttpClient;

    private static final long HISTORY_EXPIRE = 60 * 60 * 24 * 3;

    private static final String DEEPSEEK_API_URL = "https://api.deepseek.com/chat/completions";
    private static final String API_KEY = "sk-f20ea3fd499447f8901bef1b62402c10";

    public String handleMessage(String openId, String query) {
        List<Map<String,String>> conversationHistory = getOrInitHistory(openId);
        Map<String,String> data = new HashMap<>();
        data.put("role","user");
        data.put("content",query);
        conversationHistory.add(data);
        if(conversationHistory.size()>10){
            conversationHistory=conversationHistory.subList(
                    conversationHistory.size()-4,conversationHistory.size()
            );
        }
        String response = queryDeepSeek(conversationHistory);
        Map<String,String> answer = new HashMap<>();
        answer.put("role","assistant");
        answer.put("content",response);
        conversationHistory.add(answer);
        saveHistory(openId, conversationHistory);
        return response;
    }

    private String queryDeepSeek(List<Map<String,String>> conversationHistory) {
        JSONObject requestBody = new JSONObject();
        requestBody.put("model","deepseek-chat");
        JSONArray messages = new JSONArray();
        messages = JSONArray.parseArray(JSON.toJSONString(conversationHistory));
        requestBody.put("messages",messages);
        requestBody.put("stream",false);
        requestBody.put("temperature",1.3);
        requestBody.put("max_tokens",300);
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType, JSON.toJSONString(requestBody));
        Request request = new Request.Builder()
                .url(DEEPSEEK_API_URL)
                .addHeader("Authorization","Bearer " + API_KEY)
                .addHeader("Content-Type","application/json")
                .post(body)
                .build();
        try {
            try (Response response = okHttpClient.newCall(request).execute()) {
                if(response.isSuccessful()) {
                    String responseBody = response.body().string();
                    JSONObject jsonResponse = JSON.parseObject(responseBody);
                    return jsonResponse.getJSONArray("choices").getJSONObject(0).getJSONObject("message").getString("content");
                }else{
                    return "请求失败"+response.code();
                }
            }
        }catch (Exception e){
            log.info("请求失败 {}",requestBody,e);
            return "请求繁忙请稍后再试";
        }
    }
    private List<Map<String,String>> getOrInitHistory(String openId){
        String key = "chat:history:" + openId;
        String historyJson = stringRedisTemplate.opsForValue().get(key);
        if(StringUtils.isBlank(historyJson)){
            return new ArrayList<>();
        }
        return new Gson().fromJson(historyJson, new TypeToken<List<Map<String, String>>>() {}.getType());
    }
    private void saveHistory(String openId, List<Map<String,String>> history){
        String key = "chat:history:" + openId;
        String historyJson = JSON.toJSONString(history);
        stringRedisTemplate.opsForValue().set(key, historyJson,HISTORY_EXPIRE, TimeUnit.SECONDS);
    }
}
